package xj.graph2d;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

import javax.swing.JComponent;

public class Ruler extends JComponent {

  public static final int HORIZONTAL = 0;

  public static final int VERTICAL = 1;

  public Ruler(int orientation, ScrollCanvas scrollcanvas) {
    this.orientation = orientation;
    this.scrollcanvas = scrollcanvas;
    if (scrollcanvas != null) {
      canvas = scrollcanvas.getCanvas();
      if (canvas != null) {
	view = canvas.getView();
      }
    }
  }

  public void setStart(float start) {
    this.start = start;
    repaint();
  }

  public float getStart() {
    return start;
  }

  static final Font labelFont = new Font("SansSerif", Font.PLAIN, 10);

  @Override
  public void paint(Graphics g) {
    Dimension dim = getSize();
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
	RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setFont(labelFont);
    FontMetrics fm = g2.getFontMetrics();
    g2.clipRect(0, 0, dim.width, dim.height);
    g2.setColor(Color.orange);
    g2.fill3DRect(0, 0, dim.width, dim.height, true);
    g2.setColor(Color.black);

    if (view == null && scrollcanvas != null) {
      canvas = scrollcanvas.getCanvas();
      if (canvas != null) {
	view = canvas.getView();
      }
    }

    if (canvas != null && view != null) {
      float s = view.getScaleFactor();
      Document doc = view.getDocument();
      int unit = doc.getUnit();
      float gap = 10;
      int majorGap = 5;
      if (unit == Document.UNIT_CM) {
	gap = (float) Document.POINTS_PER_CM / 4;
	majorGap = 4;
      } else if (unit == Document.UNIT_INCH) {
	gap = (float) Document.POINTS_PER_INCH / 4;
	majorGap = 4;
      }

      Rectangle2D r = canvas.getVirtualCanvasRectangle();
      float width = (float) r.getWidth();
      float height = (float) r.getHeight();
      float bound;
      int bottom;
      AffineTransform af = new AffineTransform();
      if (orientation == HORIZONTAL) {
	af.translate(-start * s, 0);
	bound = width * s;
	bottom = dim.height - 1;
      } else {
	af.rotate(-Math.PI / 2);
	af.translate(start * s, 0);
	bound = height * s;
	bottom = dim.width - 1;
      }

      g2.transform(af);
      int i = 0;
      float x = 0;
      while (Math.abs(x) <= bound) {
	int ix = Math.round(x);
	int h = 5;
	if (i % majorGap == 0) {
	  h = 8;
	  int xs = 1;
	  if (s < 1f) {
	    xs = (int) Math.floor(1f / s);
	  }
	  if (i % (majorGap * xs) == 0) {
	    String label;
	    if (unit == Document.UNIT_PIXEL) {
	      label = Integer.toString(i * 10);
	    } else {
	      label = Integer.toString(i / 4);
	    }
	    int sw = fm.stringWidth(label);
	    g2.drawString(label, ix - sw / 2, bottom - h - 1);
	  }
	}
	g2.drawLine(ix, bottom, ix, bottom - h);

	if (orientation == HORIZONTAL) {
	  x += gap * s;
	} else {
	  x -= gap * s;
	}
	i++;
      }
    }
  }

  protected int orientation;

  protected ScrollCanvas scrollcanvas;

  protected DrawCanvas canvas;

  protected View view;

  protected float start;

}
